package
{
	public class TestRay_Tile
	{
		private static var TestRay_Tile_Functions:Object;

		public static function initialize():void
		{
			TestRay_Tile.TestRay_Tile_Functions = new Object();
			TestRay_Tile.TestRay_Tile_Functions[TileMapCell.CTYPE_FULL] = TestRay_Tile.TestRay_Full;
			TestRay_Tile.TestRay_Tile_Functions[TileMapCell.CTYPE_45DEG] = TestRay_Tile.TestRay_45Deg;
			TestRay_Tile.TestRay_Tile_Functions[TileMapCell.CTYPE_CONCAVE] = TestRay_Tile.TestRay_Concave;
			TestRay_Tile.TestRay_Tile_Functions[TileMapCell.CTYPE_CONVEX] = TestRay_Tile.TestRay_Convex;
			TestRay_Tile.TestRay_Tile_Functions[TileMapCell.CTYPE_22DEGs] = TestRay_Tile.TestRay_22DegS;
			TestRay_Tile.TestRay_Tile_Functions[TileMapCell.CTYPE_22DEGb] = TestRay_Tile.TestRay_22DegB;
			TestRay_Tile.TestRay_Tile_Functions[TileMapCell.CTYPE_67DEGs] = TestRay_Tile.TestRay_67DegS;
			TestRay_Tile.TestRay_Tile_Functions[TileMapCell.CTYPE_67DEGb] = TestRay_Tile.TestRay_67DegB;
			TestRay_Tile.TestRay_Tile_Functions[TileMapCell.CTYPE_HALF] = TestRay_Tile.TestRay_Half;
		}

		public static function TestRayTile(out:Vector2, px:Number, py:Number, dx:Number, dy:Number, t:TileMapCell):Boolean
		{
			if (0 < t.ID)
			{
				return TestRay_Tile_Functions[t.CTYPE](out, px, py, dx, dy, t);
			}
			return false;
		}

		public static function TestRay_Circle(out, px, py, dx, dy, obj):Boolean
		{
			var abx = (px - obj.pos.x);
			var aby = (py - obj.pos.y);
			var a = ((dx * dx) + (dy * dy));
			var b = (2 * ((dx * abx) + (dy * aby)));
			var rad = obj.r;
			var c = (((abx * abx) + (aby * aby)) - (rad * rad));
			var q = ((b * b) - ((4 * a) * c));
			if (0 <= q)
			{
				var sq = Math.sqrt(q);
				var d = (1 / (2 * a));
				var _local1 = ((-b) + sq) * d;
				var _local3 = ((-b) - sq) * d;
				var _local2;
				if (_local3 < 0)
				{
					if (_local1 < 0)
					{
						return(false);
					}
					else
					{
						_local2 = _local1;
					}
				}
				else if (_local1 < 0)
				{
					_local2 = _local3;
				}
				else if (_local3 < _local1)
				{
					_local2 = _local3;
				}
				else
				{
					_local2 = _local1;
				}
				out.x = px + (_local2 * dx);
				out.y = py + (_local2 * dy);
				return(true);
			}
			return(false);
			return(_local3);
		}

		public static function TestRay_AABB(out, px, py, dx, dy, obj):Boolean
		{
			var _local3 = py;
			var bx = obj.pos.x;
			var _local2 = obj.pos.y;
			var xw = obj.xw;
			var yw = obj.yw;
			var xval;
			var yval;
			if (px < bx)
			{
				xval = bx - xw;
			}
			else
			{
				xval = bx + xw;
			}
			if (_local3 < _local2)
			{
				yval = _local2 - yw;
			}
			else
			{
				yval = _local2 + yw;
			}
			var _local1;
			var x0;
			var y0;
			var x1;
			var y1;
			if (dx == 0)
			{
				if (dy == 0)
				{
					return(false);
				}
				else
				{
					x0 = bx - xw;
					x1 = bx + xw;
					y0 = (y1 = yval);
					_local1 = (yval - _local3) / dy;
				}
			}
			else if (dy == 0)
			{
				y0 = _local2 - yw;
				y1 = _local2 + yw;
				x0 = (x1 = xval);
				_local1 = (xval - px) / dx;
			}
			else
			{
				var tX = ((xval - px) / dx);
				var tY = ((yval - _local3) / dy);
				if (tX < tY)
				{
					x0 = bx - xw;
					x1 = bx + xw;
					y0 = (y1 = yval);
					_local1 = tY;
				}
				else
				{
					y0 = _local2 - yw;
					y1 = _local2 + yw;
					x0 = (x1 = xval);
					_local1 = tX;
				}
			}
			if (0 < _local1)
			{
				var qx = (px + (100 * dx));
				var qy = (_local3 + (100 * dy));
				var areaPQ0 = (((qx - px) * (y0 - _local3)) - ((x0 - px) * (qy - _local3)));
				var areaPQ1 = (((qx - px) * (y1 - _local3)) - ((x1 - px) * (qy - _local3)));
				if ((areaPQ0 * areaPQ1) < 0)
				{
					out.x = px + (_local1 * dx);
					out.y = _local3 + (_local1 * dy);
					return(true);
				}
				return(false);
			}
			return(false);
			return(_local3);
		}

		private static function TestRay_Full(out:Vector2, px:Number, py:Number, dx:Number, dy:Number, tile:TileMapCell):Boolean
		{
			return false;
		}

		private static function TestRay_45Deg(out:Vecotr2, px:Number, py:Number, dx:Number, dy:Number, tile:TileMap):Boolean
		{
			var sx = tile.signx;
			var sy = tile.signy;
			if (0 <= sx * dx + sy * dy)
			{
				return false;
			}
			var ux = (sx * tile.xw);
			var _local3 = (-sy) * tile.yw;
			var wx = (tile.pos.x - px);
			var wy = (tile.pos.y - py);
			var _local2 = ((dy * wx) - (dx * wy)) / ((dx * _local3) - (dy * ux));
			if (Math.abs(_local2) <= 1)
			{
				out.x = tile.pos.x + (_local2 * ux);
				out.y = tile.pos.y + (_local2 * _local3);
				return true;
			}
			return false;
		}

		private static function TestRay_Concave(out, px, py, dx, dy, t):Boolean
		{
			var _local1 = dy;
			var _local2 = dx;
			var _local3 = t;
			var sx = _local3.signx;
			var sy = _local3.signy;
			if (0 <= ((sx * _local2) + (sy * _local1)))
			{
				return(false);
			}
			var ux = (sx * _local3.xw);
			var uy = ((-sy) * _local3.yw);
			var wx = (_local3.pos.x - px);
			var wy = (_local3.pos.y - py);
			var s = (((_local1 * wx) - (_local2 * wy)) / ((_local2 * uy) - (_local1 * ux)));
			if (Math.abs(s) <= 1)
			{
				var abx = ((-ux) - wx);
				var aby = (uy - wy);
				var a = ((_local2 * _local2) + (_local1 * _local1));
				var b = (2 * ((_local2 * abx) + (_local1 * aby)));
				var rad = (_local3.xw * 2);
				var c = (((abx * abx) + (aby * aby)) - (rad * rad));
				var q = ((b * b) - ((4 * a) * c));
				if (0 <= q)
				{
					var sq = Math.sqrt(q);
					var d = (1 / (2 * a));
					var u0 = (((-b) + sq) * d);
					var u1 = (((-b) - sq) * d);
					if (u1 < u0)
					{
						out.x = px + (u0 * _local2);
						out.y = py + (u0 * _local1);
					}
					else
					{
						out.x = px + (u1 * _local2);
						out.y = py + (u1 * _local1);
					}
					return(true);
				}
				return(false);
			}
			return(false);
			return(_local3);
		}

		private static function TestRay_Convex(out, px, py, dx, dy, t):Boolean
		{
			var _local1 = t;
			var sx = _local1.signx;
			var sy = _local1.signy;
			var abx = (px - (_local1.pos.x - (sx * _local1.xw)));
			var aby = (py - (_local1.pos.y - (sy * _local1.yw)));
			var a = ((dx * dx) + (dy * dy));
			var _local2 = 2 * ((dx * abx) + (dy * aby));
			var rad = (_local1.xw * 2);
			var c = (((abx * abx) + (aby * aby)) - (rad * rad));
			var q = ((_local2 * _local2) - ((4 * a) * c));
			if (0 <= q)
			{
				var sq = Math.sqrt(q);
				var d = (1 / (2 * a));
				var u0 = (((-_local2) + sq) * d);
				var _local3 = ((-_local2) - sq) * d;
				if (_local3 < u0)
				{
					out.x = px + (_local3 * dx);
					out.y = py + (_local3 * dy);
				}
				else
				{
					out.x = px + (u0 * dx);
					out.y = py + (u0 * dy);
				}
				return(true);
			}
			return(false);
			return(_local3);
		}

		private static function TestRay_Half(out, px, py, dx, dy, t):Boolean
		{
			var _local1 = t;
			var sx = _local1.signx;
			var _local3 = _local1.signy;
			var wx = (_local1.pos.x - px);
			var wy = (_local1.pos.y - py);
			if (0 <= ((wx * sx) + (wy * _local3)))
			{
				out.x = px;
				out.y = py;
				return(true);
			}
			if (0 <= ((sx * dx) + (_local3 * dy)))
			{
				return(false);
			}
			var ux = (_local3 * _local1.xw);
			var uy = (sx * _local1.yw);
			var _local2 = ((dy * wx) - (dx * wy)) / ((dx * uy) - (dy * ux));
			if (Math.abs(_local2) <= 1)
			{
				out.x = _local1.pos.x + (_local2 * ux);
				out.y = _local1.pos.y + (_local2 * uy);
				return(true);
			}
			return(false);
			return(_local3);
		}

		private static function TestRay_22DegS(out, px, py, dx, dy, t):Boolean
		{
			var _local1 = t;
			var sx = _local1.sx;
			var sy = _local1.sy;
			var _local3 = _local1.signx;
			var signy = _local1.signy;
			var wx = ((_local1.pos.x - (_local3 * _local1.xw)) - px);
			var wy = (_local1.pos.y - py);
			if ((0 <= (wx * _local3)) && (0 <= (wy * signy)))
			{
				out.x = px;
				out.y = py;
				return(true);
			}
			if (0 <= ((sx * dx) + (sy * dy)))
			{
				return(false);
			}
			wx = wx + (_local3 * _local1.xw);
			var vy = ((signy * 0.5) * _local1.yw);
			wy = wy - vy;
			var ux = ((-signy) * _local1.xw);
			var uy = ((0.5 * _local3) * _local1.yw);
			var _local2 = ((dy * wx) - (dx * wy)) / ((dx * uy) - (dy * ux));
			if (Math.abs(_local2) <= 1)
			{
				out.x = _local1.pos.x + (_local2 * ux);
				out.y = (_local1.pos.y - vy) + (_local2 * uy);
				return(true);
			}
			return(false);
			return(_local3);
		}

		private static function TestRay_22DegB(out, px, py, dx, dy, t):Boolean
		{
			var _local1 = t;
			var sx = _local1.sx;
			var sy = _local1.sy;
			var signx = _local1.signx;
			var signy = _local1.signy;
			var wx = (_local1.pos.x - px);
			var _local3 = _local1.pos.y - py;
			if (((wx * signx) <= 0) && (0 <= (_local3 * signy)))
			{
				out.x = px;
				out.y = py;
				return(true);
			}
			if (0 <= ((sx * dx) + (sy * dy)))
			{
				return(false);
			}
			var vy = ((signy * 0.5) * _local1.yw);
			_local3 = _local3 + vy;
			var ux = ((-signy) * _local1.xw);
			var uy = ((0.5 * signx) * _local1.yw);
			var _local2 = ((dy * wx) - (dx * _local3)) / ((dx * uy) - (dy * ux));
			if (Math.abs(_local2) <= 1)
			{
				out.x = _local1.pos.x + (_local2 * ux);
				out.y = (_local1.pos.y + vy) + (_local2 * uy);
				return(true);
			}
			return(false);
			return(_local3);
		}

		private static function TestRay_67DegS(out, px, py, dx, dy, t):Boolean
		{
			var _local1 = t;
			var sx = _local1.sx;
			var sy = _local1.sy;
			var signx = _local1.signx;
			var _local3 = _local1.signy;
			var wx = (_local1.pos.x - px);
			var wy = ((_local1.pos.y - (_local3 * _local1.yw)) - py);
			if ((0 <= (wx * signx)) && (0 <= (wy * _local3)))
			{
				out.x = px;
				out.y = py;
				return(true);
			}
			if (0 <= ((sx * dx) + (sy * dy)))
			{
				return(false);
			}
			wy = wy + (_local3 * _local1.yw);
			var vx = ((signx * 0.5) * _local1.xw);
			wx = wx - vx;
			var ux = ((-0.5 * _local3) * _local1.xw);
			var uy = (signx * _local1.yw);
			var _local2 = ((dy * wx) - (dx * wy)) / ((dx * uy) - (dy * ux));
			if (Math.abs(_local2) <= 1)
			{
				out.x = (_local1.pos.x - vx) + (_local2 * ux);
				out.y = _local1.pos.y + (_local2 * uy);
				return(true);
			}
			return(false);
			return(_local3);
		}

		private static function TestRay_67DegB(out, px, py, dx, dy, t):Boolean
		{
			var _local1 = t;
			var sx = _local1.sx;
			var sy = _local1.sy;
			var signx = _local1.signx;
			var signy = _local1.signy;
			var _local3 = _local1.pos.x - px;
			var wy = (_local1.pos.y - py);
			if (((wy * signy) <= 0) && (0 <= (_local3 * signx)))
			{
				out.x = px;
				out.y = py;
				return(true);
			}
			if (0 <= ((sx * dx) + (sy * dy)))
			{
				return(false);
			}
			var vx = ((signx * 0.5) * _local1.xw);
			_local3 = _local3 + vx;
			var ux = ((-0.5 * signy) * _local1.xw);
			var uy = (signx * _local1.yw);
			var _local2 = ((dy * _local3) - (dx * wy)) / ((dx * uy) - (dy * ux));
			if (Math.abs(_local2) <= 1)
			{
				out.x = (_local1.pos.x + vx) + (_local2 * ux);
				out.y = _local1.pos.y + (_local2 * uy);
				return(true);
			}
			return(false);
			return(_local3);
		}
	}
}